/*
 * Copyright 2014 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package cn.bbstone.pisces2.server;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.bbstone.pisces2.comm.codec.ReqFileDecoder;
import cn.bbstone.pisces2.listener.OpEnum;
import cn.bbstone.pisces2.listener.OpUtil;
import cn.bbstone.pisces2.proto.req.ReqFile;
import cn.bbstone.pisces2.server.base.ReqDispatcher;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

/**
 * cannot used ObjectEncoder/ObjectDecoder, because FileRegion write bytes to socket channel directly,
 * and no api to set chunk to a object,
 *
 * the solution just send every chunk with BFileResponse prefix, and end with delimiter "__BBSTONE_BFILE_END__"
 *
 */
public class FileServerHandler extends SimpleChannelInboundHandler<ByteBuf> {
    private static Logger log = LoggerFactory.getLogger(FileServerHandler.class);


	/**
	 * when connected
	 * 
	 */
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
//        ctx.writeAndFlush("HELLO: Type the path of the file to retrieve.\n");
    	log.info("client connected, remoteIp: {}", ctx.channel().remoteAddress());
    	// notify UI load connectionInfo
//    	CtxUtil.addConnInfo(ctx.channel().remoteAddress().toString());
    	OpUtil.execListener(OpEnum.s5_client_connected, ctx.channel().remoteAddress().toString());
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
        if (in != null) {
            ReqFileDecoder decoder = new ReqFileDecoder();
            ReqFile reqFile = decoder.decode(ctx, in);
            ReqDispatcher.dispatch(ctx, reqFile);
        }
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        if (ctx.channel().isActive()) {
            ctx.writeAndFlush("ERR: " +
                    cause.getClass().getSimpleName() + ": " +
                    cause.getMessage() + '\n').addListener(ChannelFutureListener.CLOSE);
        }
    }

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		super.channelInactive(ctx);
		// notify UI load connectionInfo
//    	CtxUtil.removeConnInfo(ctx.channel().remoteAddress().toString());
    	OpUtil.execListener(OpEnum.s6_client_disconnected, ctx.channel().remoteAddress().toString());
	}
    
    

}

